package com.myproject.mall.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.myproject.mall.common.config.RabbitMQConfig;
import com.myproject.mall.common.exception.GlobalException;
import com.myproject.mall.domain.dto.OrderForm;
import com.myproject.mall.domain.entity.Goods;
import com.myproject.mall.domain.entity.Order;
import com.myproject.mall.domain.enums.OrderStatus;
import com.myproject.mall.goods.mapper.GoodsMapper;
import com.myproject.mall.goods.mapper.OrderMapper;
import com.myproject.mall.goods.service.IOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedissonClient redissonClient;

    @Transactional
    @Override
    public OrderForm createOrder(OrderForm order) {

        if(!checkProductAndStock(order)) throw new GlobalException("商品不存在或库存不足");

        RLock lock = redissonClient.getLock("lock:order:user:"+order.getBuyerId());
        boolean isLock = lock.tryLock();
        if(!isLock) {
            log.error("{}：下单失败", order.getBuyerId());
            return null;
        }

        try{

            if(!checkProductAndStock(order)) {
                throw new GlobalException("商品不存在或库存不足");
            }

            Order entity = Order.builder()
                    .sellerId(order.getSellerId())
                    .buyerId(order.getBuyerId())
                    .goodsId(order.getGoodsId())
                    .couponId(order.getCouponId())
                    .amount(order.getAmount())
                    .payMoney(new BigDecimal(order.getPayMoney()))
                    .actualMoney(new BigDecimal(order.getActualMoney()))
                    .payWay(order.getPayWay())
                    .status(OrderStatus.UNPAID)
                    .shipAddress(order.getShipAddress())
                    .deliveryAddress(order.getDeliveryAddress())
                    .build();
            orderMapper.insert(entity);

            goodsMapper.update(new LambdaUpdateWrapper<Goods>()
                    .eq(Goods::getId, order.getGoodsId())
                    .setSql("goods_amount = goods_amount - " + order.getAmount()));

            log.info("创建订单{}成功", order.getId());

            rabbitTemplate.convertAndSend(
                    RabbitMQConfig.ORDER_TOPIC_EXCHANGE,
                    RabbitMQConfig.ORDER_CREATE_ROUTING_KEY,
                    entity);
            log.info("发送订单创建消息{}成功", order.getId());

//            延迟消息，实现超时取消订单
            rabbitTemplate.convertAndSend(
                    RabbitMQConfig.ORDER_TOPIC_EXCHANGE,
                    RabbitMQConfig.ORDER_TIMEOUT_ROUTING_KEY,
                    entity.getId(),
                    message -> {
                        message.getMessageProperties().setDelayLong(30 * 60 * 1000L);
                        return message;
                    });
            log.info("发送订单超时取消检测消息成功:{}", order.getId());
        }
        catch (IllegalStateException e) {
            throw new GlobalException("创建订单失败");
        }
        finally {
            lock.unlock();
        }

        return order;
    }

    @Transactional
    @Override
    public void payOrder(String orderId) {
        log.info("开始支付订单{}", orderId);

        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new GlobalException("订单不存在");
        }

        if(order.getStatus()!= OrderStatus.UNPAID) {
            throw new GlobalException("订单状态错误");
        }

        order.setStatus(OrderStatus.PAID);
        orderMapper.updateById(order);
//        TODO 支付处理
        log.info("订单{}支付成功", orderId);

        rabbitTemplate.convertAndSend(
                RabbitMQConfig.ORDER_TOPIC_EXCHANGE,
                RabbitMQConfig.ORDER_PAY_ROUTING_KEY,
                order);
        log.info("发送订单支付成功消息成功:{}", orderId);
    }

    private boolean checkProductAndStock(Order order) {
        Goods goods = goodsMapper.selectById(order.getGoodsId());
        return goods != null && goods.getAmount() >= order.getAmount();
    }

    @Transactional
    @Override
    public void cancelOrder(String orderId) {
        log.info("取消订单{}开始", orderId);

        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new GlobalException("订单不存在");
        }

        if(order.getStatus() == OrderStatus.CANCELED ||
                order.getStatus() == OrderStatus.COMPLETED ||
                order.getStatus() == OrderStatus.DELETED ||
                order.getStatus() == OrderStatus.REFUND) {
            throw new GlobalException("订单状态不允许取消");
        }

        rabbitTemplate.convertAndSend(
                RabbitMQConfig.ORDER_TOPIC_EXCHANGE,
                RabbitMQConfig.ORDER_CANCEL_ROUTING_KEY,
                order);
    }

    private boolean checkProductAndStock(OrderForm order) {
        Goods goods = goodsMapper.selectById(order.getGoodsId());
        if(goods == null || goods.getAmount() < order.getAmount()) {
            return false;
        }
        return true;
    }

    @Override
    public List<OrderForm> getOrderByStatus(String status) {
        return List.of();
    }

    @Override
    public List<OrderForm> getSaleOrder(String status) {
        return List.of();
    }
}
